<?php

namespace pmvc\mvc\security;

use pmvc\mvc\security\basic\DataSourceUserDao;
use pmvc\mvc\security\basic\BasicAuthenticator;
use pmvc\mvc\security\basic\BasicAuthenticationProvider;
use pmvc\ioc\FactoryObject;
use pmvc\ioc\Ordered;

use Exception;

/**
 * Factory class for SecurityRequest filter to ease
 * the basic use of the security framework.
 * @author brian
 *
 */
class SecurityRequestFilterFactoryObject
	implements FactoryObject {

	public $authenticationProviders		= Array();
	public $authenticators				= Array();
	public $authenticationListeners		= Array();

	public $urlPatternRoleMap			= Array();
	public $anonymousRoles				= Array();

	public $nextUrlParamName			= "nextUrl";
	public $loginFailedParamName		= "loginFailed";
	
	public $loginFormUrl				= "/login.html";
	public $loginFailedUrl				= "/login.html";
	public $loginSuccessUrl				= "/";
	public $accessDeniedUrl				= "/login.html";
	public $logoutSuccessUrl			= "/";

	public $loginActionUrlPattern		= "^/login.do";
	public $logoutActionUrlPattern		= "^/logout.do";

	public $userDao					= null;
	public $passwordEncoder			= null;
	public $dataSource				= null;
	public $roleDelimiter			= ",";
	public $sqlQuery				= null;
	public $useMd5PasswordEncoder	= false;
	public $salt					= "";
	public $saltPrefix 				= "";
	public $saltPostfix 			= "";
	public $urlPatternRoleMapNames	= Array();
	public $anonymousRoleNames		= null;
	public $order					= Ordered::LOWEST_PRECEDENCE;

	/**
	 * {@inheritDoc}
	 * @see pmvc\ioc.FactoryObject::createObject()
	 */
	public function createObject() {

		// create it
		$ret = new SecurityRequestFilter();

		// AuthenticationProvider
		if (isset($this->authenticationProviders) && !empty($this->authenticationProviders)) {
			$ret->setAuthenticationProviders($this->authenticationProviders);
		} else {
			$ret->setAuthenticationProviders(Array(new BasicAuthenticationProvider()));
		}

		// Authenticator
		if (isset($this->authenticators) && !empty($this->authenticators)) {
			$ret->setAuthenticators($this->authenticators);
		} else {
			
			// create password encoder
			if (!isset($this->passwordEncoder) && $this->useMd5PasswordEncoder) {
				$this->passwordEncoder = new MD5PasswordEncoder();
				$this->passwordEncoder->setSalt($this->salt);
				$this->passwordEncoder->setSaltPrefix($this->saltPrefix);
				$this->passwordEncoder->setSaltPostfix($this->saltPostfix);
			}
			
			// create user dao
			if (!isset($this->userDao)) {
				if (!isset($this->dataSource)) {
					throw new Exception("dataSource must be set");
				} else 	if (!isset($this->sqlQuery)) {
					throw new Exception("sqlQuery must be set");
				}
				$this->userDao = new DataSourceUserDao();
				$this->userDao->setDataSource($this->dataSource);
				$this->userDao->setRoleDelimiter($this->roleDelimiter);
				$this->userDao->setSqlQuery($this->sqlQuery);
			}
			
			// create authenticator
			$authenticator = new BasicAuthenticator();
			$authenticator->setUserDao($this->userDao);
			$authenticator->setPasswordEncoder($this->passwordEncoder);
			
			// set it
			$ret->setAuthenticators(Array($authenticator));
		}

		// AuthenticationListener
		if (isset($this->authenticationListeners) && !empty($this->authenticationListeners)) {
			$ret->setAuthenticationListeners($this->authenticationListeners);
		}

		// $order
		if (isset($this->order)) {
			$ret->setOrder($this->order);
		}

		// $urlPatternRoleMap
		if (isset($this->urlPatternRoleMap) && !empty($this->urlPatternRoleMap)) {
			$ret->setUrlPatternRoleMap($this->urlPatternRoleMap);
		} else if (isset($this->urlPatternRoleMapNames) && !empty($this->urlPatternRoleMapNames)) {
			$ret->setUrlPatternRoleMapNames($this->urlPatternRoleMapNames);
		}
		
		// $anonymousRoles
		$ret->setAnonymousRoles($this->anonymousRoles);
		if (isset($this->anonymousRoleNames) && !empty($this->anonymousRoleNames)) {
			$ret->setAnonymousRoleNames($this->anonymousRoleNames);
		}
		
		// $nextUrlParamName
		if (isset($this->nextUrlParamName) && !empty($this->nextUrlParamName)) {
			$ret->setNextUrlParamName($this->nextUrlParamName);
		}
		
		// $loginFormUrl
		if (isset($this->loginFormUrl) && !empty($this->loginFormUrl)) {
			$ret->setLoginFormUrl($this->loginFormUrl);
		}
		
		// $loginActionUrlPattern
		if (isset($this->loginActionUrlPattern) && !empty($this->loginActionUrlPattern)) {
			$ret->setLoginActionUrlPattern($this->loginActionUrlPattern);
		}
		
		// $loginFailedUrl
		if (isset($this->loginFailedUrl) && !empty($this->loginFailedUrl)) {
			$ret->setLoginFailedUrl($this->loginFailedUrl);
		}
		
		// $loginSuccessUrl
		if (isset($this->loginSuccessUrl) && !empty($this->loginSuccessUrl)) {
			$ret->setLoginSuccessUrl($this->loginSuccessUrl);
		}
		
		// $accessDeniedUrl
		if (isset($this->accessDeniedUrl) && !empty($this->accessDeniedUrl)) {
			$ret->setAccessDeniedUrl($this->accessDeniedUrl);
		}
		
		// $logoutActionUrlPattern
		if (isset($this->logoutActionUrlPattern) && !empty($this->logoutActionUrlPattern)) {
			$ret->setLogoutActionUrlPattern($this->logoutActionUrlPattern);
		}
		
		// $logoutSuccessUrl
		if (isset($this->logoutSuccessUrl) && !empty($this->logoutSuccessUrl)) {
			$ret->setLogoutSuccessUrl($this->logoutSuccessUrl);
		}

		// return it
		return $ret;
	}
}

?>